﻿#include "behavior.h"
#include <chrono>

using namespace bt;
Behavior::Behavior()
{

}

Behavior::~Behavior()
{

}

STATE Behavior::Tick()
{
	if (status_ == INVALID)
	{
		Init();
	}

	//这里执行成功会返回SUCCESS
	if(status_ == RUNNING)
		status_ = Update();

	if (status_ == FAILURE)
	{
		//失败处理
		Terminate();
	}

	return status_;
}

STATE Behavior::GetStatus() const
{
	return status_;
}

bool Behavior::IsRunning() const
{
	return status_ == RUNNING;
}

void Behavior::SetName(const char *name)
{
	name_ = name;
}

const char* Behavior::GetName() const
{
	return name_;
}

void Composite::AddChild(Behavior *node)
{
	childs_.push_back(node);
}

Behavior* Composite::GetChild(int idx)
{
	if (idx >= childs_.size())
		return nullptr;
	return childs_[idx];
}

int Composite::GetChildCount()
{
	return (int)childs_.size();
}

STATE Sequence::Update()
{
	while (true)
	{
		auto child = GetChild(cur_idx);
		if (child == nullptr)
			return FAILURE;
		STATE s = child->Tick();
		if (s != SUCCESS)
		{
			return s;
		}
	
		if (++cur_idx >= GetChildCount())
		{
			return SUCCESS;
		}
	}
}

bt::STATE Selector::Update()
{
	while (true)
	{
		Behavior *child = GetChild(cur_idx);
		if (child == nullptr)
			return FAILURE;
		STATE s = child->Tick();
		if (s == SUCCESS)
			return s;
		
		if (++cur_idx >= GetChildCount() - 1)
		{
			return FAILURE;
		}
	}
}

void Decorator::SetChild(Behavior *node)
{
	child_ = node;
}

STATE Repert::Update()
{
	child_->Tick();
	if (limitCount_ > 0 && ++count_ >= limitCount_)
	{
		return SUCCESS;
	}
	return RUNNING;
}

bt::STATE Timeout::Update()
{
	auto time_now = std::chrono::system_clock::now();
	auto duration_in_ms = std::chrono::duration_cast<std::chrono::milliseconds>(time_now.time_since_epoch());
	if (duration_in_ms.count() > mstime_)
	{
		return child_->Tick();
	}
	return RUNNING;
}

void Tree::SetRoot(Behavior *root)
{
	root_ = root;
}

STATE Tree::Update()
{
	return root_->Tick();
}
